package com.xyw.code.gateway.web.filter;

import com.alibaba.fastjson.JSONObject;
import com.xyw.code.authentication.client.service.IAuthService;
import com.xyw.code.gateway.web.service.IPermissionService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import static com.xyw.code.common.core.constant.SecurityConstant.X_CLIENT_TOKEN_USER;


/**
 * Created with IntelliJ IDEA.
 * User: xuyiwei
 * Date: 2020/3/3
 * Time: 下午7:30
 * Email: 1328312923@qq.com
 * Description: No Description
 **/
@Configuration
@Slf4j
public class AccessGatewayFilter implements GlobalFilter {

    @Autowired
    private IPermissionService permissionService;

    @Autowired
    private IAuthService authService;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String authorization = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
        String method = request.getMethodValue();
        String url = request.getPath().value();
        log.info("getPath().value():{}",request.getPath().value());
        log.info("getPath().contextPath().value():{}",request.getPath().contextPath().value());
        if(authService.ignoreUrl(url)){
            return chain.filter(exchange);
        }
        if(permissionService.auth(authorization,url,method)){
            ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
            builder.header(X_CLIENT_TOKEN_USER, getUser(authorization));
            return chain.filter(exchange.mutate().request(builder.build()).build());
        }
        return unauthorized(exchange);


    }

    private String getUser(String authorization) {
        //调用第三方接口  返回用户json
        Jws<Claims> jws = authService.getJwtClaims(authorization);
        Claims claims = jws.getBody();
        return JSONObject.toJSONString(claims);
    }

    /**
     * 网关拒绝，返回401
     *
     * @param
     */
    private Mono<Void> unauthorized(ServerWebExchange serverWebExchange) {
        serverWebExchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        DataBuffer buffer = serverWebExchange.getResponse()
                .bufferFactory().wrap(HttpStatus.UNAUTHORIZED.getReasonPhrase().getBytes());
        return serverWebExchange.getResponse().writeWith(Flux.just(buffer));
    }
}
